#include "client.h"

int main(int argc, char *argv[]) {
    ARGS_CHECK(argc, 3);
    char buf[1024] = {0};
    char cmd[128] = {0};
    char path1[128] = {0};
    char path2[128] = {0};
    char s[] = "mycloud> ";

    /* TCP 连接 */
    int socketFd;
    tcpClientInit(argv[1], argv[2], &socketFd);
    
    printf("===============================================\n");
    printf("|                  MYCLOUD                    |\n");
    printf("|                 verson 3.0                  |\n");
    printf("===============================================\n\n");
    

    while (1) {
        
        char ss[] = "Enter l to log in, enter s to sign up: ";
        write(STDOUT_FILENO, ss, strlen(ss));
        char word[1024] = {0};
        scanf("%s", word);
        if (strcmp(word, "l") != 0 && strcmp(word, "s") != 0) {
            continue;

        /* 登录 */    
        } else if (strcmp(word, "l") == 0) {

            sendMessageToServer(socketFd, "0", 1);
            user_t user;
            enterUser(&user);
            ssize_t sendRet = send(socketFd, &user, sizeof(user), 0);
            ERROR_CHECK(sendRet, -1, "send");

            memset(buf, 0, sizeof(buf));
            ssize_t pRet = recv(socketFd, buf, 1, 0);
            if (!pRet) {
                close(socketFd);
                return 0;
            } else if (buf[0] == '0') {
                printf("%s: user does not exist\n\n", user.userName);
                continue;
            } else if (buf[0] == '1') {
                printf("Welcome %s\n\n", user.userName);
                write(STDOUT_FILENO, s, strlen(s));
                break;
            } else if (buf[0] == '2') {
                printf("Wrong password\n\n");
                continue;
            }
        
        /* 注册 */
        } else if (strcmp(word, "s") == 0) {

            sendMessageToServer(socketFd, "1", 1);
            user_t user;
            enterUser(&user);
            ssize_t sendRet = send(socketFd, &user, sizeof(user), 0);
            ERROR_CHECK(sendRet, -1, "send");
            memset(buf, 0, sizeof(buf));
            ssize_t pRet = recv(socketFd, buf, 1, 0);
            if (!pRet) {
                close(socketFd);
                return 0;
            } else if (buf[0] == '0') {
                printf("%s: username already exists\n\n", user.userName);
                continue;
            } else if (buf[0] == '1') {
                printf("Sign up finished\n");
                write(STDOUT_FILENO, s, strlen(s));
                break;
            }
        }
    }
    
    
    /* 监听 STDIN_FILENO 和 socketFd */
    int epollFd = epoll_create(1);
    ERROR_CHECK(epollFd, -1, "epoll_create");
    epollAdd(epollFd, STDIN_FILENO);
    epollAdd(epollFd, socketFd);
    struct epoll_event eventArr[2];
    while (1) {
        int readyCount = epoll_wait(epollFd, eventArr, 2, -1);
        ERROR_CHECK(readyCount, -1, "epoll_wait");
        for (int i = 0; i < readyCount; ++i) {
            
            if (eventArr[i].data.fd == STDIN_FILENO) {
                
                memset(buf, 0, sizeof(buf));
                ssize_t stdinLength = recvStdin(buf, sizeof(buf));
                if (!stdinLength) {
                    close(epollFd);
                    close(socketFd);
                    return 0;
                } 
                
                /* 解析命令 */
                memset(cmd, 0, sizeof(cmd));
                memset(path1, 0, sizeof(path1));
                memset(path2, 0, sizeof(path2));
                int ret = cutCmd(buf, cmd, path1, path2);
                if (!checkArguments(cmd, path1, path2, ret)) {
                    write(STDOUT_FILENO, s, strlen(s));
                    continue;
                }
                sendMessageToServer(socketFd, buf, stdinLength);
                if (strcmp(cmd, "puts") == 0) {
                    char md5[128] = {0};
                    changeToMd5(path1, md5);
                    sendMessageToServer(socketFd, md5, strlen(md5));
                    memset(buf, 0, sizeof(buf));
                    ssize_t r = recv(socketFd, buf, sizeof(buf), 0);
                    if (!r) {
                        close(epollFd);
                        close(socketFd);
                        return 0;
                    }
                    if (strcmp(buf, "1") == 0) {
                        printf("putting......\n");
                        printf("puts finished\n");
                        write(STDOUT_FILENO, s, strlen(s));
                        continue;
                    } else if (strcmp(buf, "0") == 0) {
                        sendFileToServer(socketFd, path1, path2);
                    } else if (strcmp(buf, "2") == 0) {
                        printf("puts: %s: No such file or directory\n", path2);
                        write(STDOUT_FILENO, s, strlen(s));
                        continue;
                    }

                } else if (strcmp(cmd, "gets") == 0) {
                    memset(buf, 0, sizeof(buf));
                    ssize_t r = recv(socketFd, buf, 1, 0);
                    if (!r) {
                        close(epollFd);
                        close(socketFd);
                        return 0;
                    }
                    if (strcmp(buf, "0") == 0) {
                        printf("gets: %s: No such file or directory\n", path1);
                        write(STDOUT_FILENO, s, strlen(s));
                        continue;
                    }
                }

            /* 事件二: 接收数据 */
            } else {
                
                ssize_t recvRet = recvMessageFromServer(socketFd, buf, sizeof(buf));
                if (!recvRet) {
                    close(epollFd);
                    close(socketFd);
                    return 0;
                }
                printf("%s\n", buf);
                
                if (strcmp(cmd, "gets") == 0) {
                    recvFileFromServer(socketFd);
                    printf("gets finished\n");
                }
                write(STDOUT_FILENO, s, strlen(s));
            }
        }
    }
    return 0;
}
